home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-07-15 | 56.6 KB | 1,802 lines | [TEXT/CWIE] |
- /*************************************************************************************
-
- File: ISpSampleADB.cp
-
- Copyright © 1996, 1997, 1998 Apple Computer, Inc., All Rights Reserved
-
-
- You may incorporate this sample code into your applications without
- restriction, though the sample code has been provided "AS IS" and the
- responsibility for its operation is 100% yours. However, what you are
- not permitted to do is to redistribute the source as "DSC Sample Code"
- after having made changes. If you're going to re-distribute the source,
- we require that you make it clear in the source that the code was
- descended from Apple Sample Code, but that you've made changes.
-
- *************************************************************************************/
-
- #ifndef __INPUTSPROCKET__
- #include <InputSprocket.h>
- #endif
-
- #include "InputSprocketDriver.h"
- #include "InputSprocketDefer.h"
- #include "ISpSampleADB.h"
- #include "ISpSampleADBMain.h"
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __QDOFFSCREEN__
- #include <QDOffscreen.h>
- #endif
-
- #ifndef __DESKBUS__
- #include <DeskBus.h>
- #endif
-
- #include "ISpPlugInUI.h"
- #include "dprintf.h"
-
- #include "ADBUtils.h"
- #include "Common.h"
- #include "DialogUtils.h"
-
- /* =============================================================================
- * ADBINIT ROUTINE
- * ========================================================================== */
- extern "C" pascal void ADBInitProc(
- char inPostprocess);
-
- extern "C" void PatchADBServiceRoutine(
- UInt8 inCommand,
- void *inBuffer,
- UInt32 inDataArea);
-
- SidewinderPro * SidewinderPro::gSidewinders[16] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-
- // string replace stuff
- static StringHandle HandleToStringHandle(Handle handle);
- static Handle StringHandleToHandle(StringHandle stringHandle);
-
- SidewinderPro::SidewinderPro(ADBAddress inADBAddr, const FSSpec &inFileSpec)
- {
- OSStatus err;
-
- // assign our arguments
- mADBAddress = inADBAddr;
- mFileSpec = inFileSpec;
-
- // clear the device
- mDevice = nil;
-
- // intialize ui variables
- mDialog = nil;
- mBaseDITLCount = nil;
- mResRef = nil;
- mVisable = false;
- mVirtualElementsValid = false; // Init has not been called yet
- mActive = false;
- mPatched = false;
- mOrphan = false;
- mADBDefer = 0;
-
- mReverseStickVertical = false;
- mReverseHatVertical = false;
- mReverseRudder = false;
- mReverseThrottle = false;
-
- // initialize old state
- mOldState.xAxis = kISpAxisMiddle;
- mOldState.yAxis = kISpAxisMiddle;
- mOldState.throttle = kISpAxisMinimum;
- mOldState.rudder = kISpAxisMiddle;
- mOldState.hat = kISpPadIdle;
-
- {
- for(UInt32 itr = 0; itr < kNumSidewinderButtons; itr++)
- { mOldState.buttons[itr] = 0; }
- }
-
- // zero high level data
- StateToHighLevelData (mOldState, mOldHLData);
- SetAsFields (mOldHLData);
-
- // zero dialog item to need mapping
- {
- for(UInt32 itr = 0; itr <= kDialogItem_NumPopups; itr++)
- { mDialogItemToNeedMapping[itr] = kUnsetIndex; }
- }
-
- ClearVirtuals();
-
- err = CreateDevice();
- WARNING(err == noErr, "CreateDevice failed in SidewinderPro::SidewinderPro");
-
- err = Patch();
- WARNING(err == noErr, "Patch failed in SidewinderPro::SidewinderPro");
-
- mActive = true;
- }
-
- SidewinderPro::~SidewinderPro()
- {
- OSStatus err = noErr;
-
- if (mPatched) { Unpatch(); }
- DisposeDevice();
- }
-
- OSStatus SidewinderPro::CreateDevice(void)
- {
- OSStatus err;
-
- // ================== step 1 create the device ==================
- err = CreateDeviceFromResource(kDeviceResource_SidewinderPro, (UInt32) this, mDevice);
- WARNING(err == noErr, "SidewinderPro CreateDeviceFromResource failed");
-
- // ================== step 2 create the axis elements ==================
- err = CreateElementFromResource(kElementResource_XAxis, kElementConfigResource_SymetricAxis, mDevice, mXAxis);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on XAxis");
-
- err = CreateElementFromResource(kElementResource_YAxis, kElementConfigResource_SymetricAxis, mDevice, mYAxis);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on YAxis");
-
- err = CreateElementFromResource(kElementResource_Throttle, kElementConfigResource_AsymetricAxis, mDevice, mThrottle);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on Throttle");
-
- err = CreateElementFromResource(kElementResource_Rudder, kElementConfigResource_SymetricAxis, mDevice, mRudder);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on Rudder");
-
- // ================== step 2 create the hat elements ==================
- err = CreateElementFromResource(kElementResource_Hat, kElementConfigResource_DPad1, mDevice, mHat);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on hat");
-
- // ================== step 3 create the button elements ==================
- err = CreateElementFromResource(kElementResource_Trigger, kElementConfigResource_Button1, mDevice, mButtons[0]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on trigger");
-
- err = CreateElementFromResource(kElementResource_TopButton, kElementConfigResource_BlankButton, mDevice, mButtons[1]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on top button");
-
- err = CreateElementFromResource(kElementResource_StickHighButton, kElementConfigResource_BlankButton, mDevice, mButtons[2]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on stick high button");
-
- err = CreateElementFromResource(kElementResource_StickLowButton, kElementConfigResource_BlankButton, mDevice, mButtons[3]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on stick low button");
-
- err = CreateElementFromResource(kElementResource_BaseFarLeft, kElementConfigResource_BlankButton, mDevice, mButtons[4]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on base far left button");
-
- err = CreateElementFromResource(kElementResource_BaseFarRight, kElementConfigResource_BlankButton, mDevice, mButtons[5]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on base far right button");
-
- err = CreateElementFromResource(kElementResource_BaseNearLeft, kElementConfigResource_BlankButton, mDevice, mButtons[6]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on base near left button");
-
- err = CreateElementFromResource(kElementResource_BaseNearRight, kElementConfigResource_BlankButton, mDevice, mButtons[7]);
- WARNING(err == noErr, "SidewinderPro CreateElementFromResource failed on base near right button");
-
- // ================== step 4 push inital values for axis elements ==================
- AbsoluteTime time = ISpUptime();
- err = ISpElement_PushSimpleData(mXAxis, mOldState.xAxis, &time);
- WARNING(err == noErr, "ISpElement_PushSimpleData failed in CreateDevice");
-
- err = ISpElement_PushSimpleData(mYAxis, mOldState.yAxis, &time);
- WARNING(err == noErr, "ISpElement_PushSimpleData failed in CreateDevice");
-
- err = ISpElement_PushSimpleData(mThrottle, mOldState.throttle, &time);
- WARNING(err == noErr, "ISpElement_PushSimpleData failed in CreateDevice");
-
- err = ISpElement_PushSimpleData(mRudder, mOldState.rudder, &time);
- WARNING(err == noErr, "ISpElement_PushSimpleData failed in CreateDevice");
-
- return err;
- }
-
- OSStatus SidewinderPro::DisposeDevice(void)
- {
- OSStatus err;
-
- err = ISpElement_Dispose(mXAxis);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on XAxis");
-
- err = ISpElement_Dispose(mYAxis);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on YAxis");
-
- err = ISpElement_Dispose(mThrottle);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on Throttle");
-
- err = ISpElement_Dispose(mRudder);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on Rudder");
-
- err = ISpElement_Dispose(mHat);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on Hat");
-
- int itr;
- for(itr = 0; itr < kNumSidewinderButtons; itr++)
- {
- err = ISpElement_Dispose(mButtons[itr]);
- WARNING(err == noErr, "SidewinderPro ISpElement_Dispose failed on a generic button");
- }
-
- err = ISpDevice_Dispose(mDevice);
- WARNING(err == noErr, "SidewinderPro ISpDevice_Dispose failed");
-
- return err;
- }
-
- /* =============================================================================
- * Patch (private)
- *
- * Installs the appropriate patch for this mouse.
- * ========================================================================== */
- OSStatus SidewinderPro::Patch(void)
- {
- WARNING(mPatched == false, "SidewinderPro patch called but we are already patched!");
-
- OSStatus err;
-
- if (!mOrphan)
- {
- WARNING((mADBAddress >= 0) && (mADBAddress <= 15), "SidewinderPro Patch bad address");
-
- err = ISpAllocateADBDeferBlock(&mADBDefer);
- if (noErr != err)
- return err; // could not allocate
-
- err = ISpInstallADBDefer(mADBDefer,mADBAddress,(ISpADBDeferCallbackProcPtr) PatchADBServiceRoutine,
- (UInt32) this,nil,nil);
-
- WARNING(err == noErr, "SidewinderPro patch failed to aquire defer block (will not patch)");
- if (noErr != err)
- return err; // could not install
- }
-
- // mark as patched
- mPatched = true;
-
- return noErr;
- }
-
-
- /* =============================================================================
- * Unpatch (private)
- *
- * Removes the patch that we installed for this mouse.
- * ========================================================================== */
- OSStatus SidewinderPro::Unpatch(void)
- {
- WARNING(mPatched == true, "SidewinderPro Unpatch called but were are not patched!");
-
- if (!mOrphan)
- {
- OSErr err;
-
- WARNING((mADBAddress >= 0) && (mADBAddress <= 15), "SidewinderPro Unpatch bad address");
-
- err = ISpRemoveADBDefer(mADBDefer);
- if (noErr != err)
- return err;
-
- // Ignore memory release errors
- (void) ISpDisposeADBDeferBlock(mADBDefer);
- }
-
- // mark as unpatched
- mPatched = false;
-
- return noErr;
- }
-
- /* =============================================================================
- * PatchADBServiceRoutine (local, c)
- *
- * ========================================================================== */
- void PatchADBServiceRoutine(
- UInt8 inCommand,
- void *inBuffer,
- UInt32 inDataArea)
- {
- SidewinderPro* sidewinderProCore = (SidewinderPro*) inDataArea;
- WARNING(sidewinderProCore != nil, "Sidewinder: patch object pointer was null");
-
- if (sidewinderProCore != nil)
- { sidewinderProCore->ParseData(inBuffer, inCommand); }
- }
-
-
- OSStatus SidewinderPro::Init(UInt32 count, ISpNeed needs[], ISpElementReference virtualElements[],
- Boolean used[], OSType appCreatorCode, OSType subCreatorCode,
- UInt32 reserved, void* reserved2)
- {
- // dont use these four
- appCreatorCode;
- subCreatorCode;
- reserved;
- reserved2;
-
- UInt32 itr;
-
- // allocate arrays to hold references and needs and copy the data in
- mReferences = (ISpElementReference *) NewPtrSysClear(count * sizeof(ISpElementReference));
- WARNING(mReferences != nil, "SidewinderPro::Init failed to allocate mReferences");
- if (mReferences == nil) { return -1; }
-
- mNeeds = (ISpNeed *) NewPtrSysClear(count * sizeof(ISpNeed));
- WARNING(mNeeds != nil, "SidewinderPro::Init failed to allocate mNeeds");
- if (mNeeds == nil)
- {
- DisposePtr((Ptr) mReferences);
- mReferences = nil;
- return - 1;
- }
-
- mNumNeeds = count;
-
- // copy the data
- for(itr = 0; itr < count; itr++)
- {
- mReferences[itr] = virtualElements[itr];
- mNeeds[itr] = needs[itr];
- }
-
- AutoConfigure(used); // sets mDialogItemToNeedMapping and the virtual elements
-
- mVirtualElementsValid = true;
- mDirty = false;
-
- // set initial values
- SetAsFields (mOldHLData);
- PushDataToVirtuals (mOldHLData);
-
- return noErr;
- }
-
- void SidewinderPro::AutoConfigure(Boolean used[])
- {
- // mVirtualElement might not be valid yet
- WARNING(mNeeds != nil, "SidewinderPro::AutoConfigure mNeeds was nil");
- WARNING(used != nil, "SidewinderPro::AutoConfigure used was nil");
- WARNING(mDialogItemToNeedMapping != nil, "SidewinderPro::AutoConfigure mDialogItemToNeepMapping was nil");
-
- // AUTOCONFIGURE
- UInt32 buttonCount = 0; // number of buttons we have auto configured
- UInt32 itr; // used for general iterating
-
- // clear out all the entries
- for(itr = 0; itr <= kDialogItem_NumPopups; itr++)
- { mDialogItemToNeedMapping[itr] = kUnsetIndex; }
-
- // first pass find movement or dpad movement needs and map them to the stick
- for(itr = 0; itr < mNumNeeds; itr++)
- {
- if (mNeeds[itr].flags & kISpNeedFlag_Utility) continue; // we don't autoconfig to utility needs
-
- if (used[itr] && (mNeeds[itr].flags & kISpNeedFlag_NoMultiConfig)) { continue; }
-
- Boolean movement_need = mNeeds[itr].theKind == kISpElementKind_Movement;
- Boolean dpad_movement_need = (mNeeds[itr].theKind == kISpElementKind_DPad) &&
- ((mNeeds[itr].theLabel == kISpElementLabel_Pad_Move) ||
- (mNeeds[itr].theLabel == kISpElementLabel_Pad_Move_Horiz));
-
- if (movement_need || dpad_movement_need)
- {
- WARNING(mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex, "Sidewinder:Movement already assigned!");
-
- mDialogItemToNeedMapping[kDialogItem_StickUp] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = itr;
-
- used[itr] = true;
-
- break;
- }
- }
-
- // second pass pov hats
- for(itr = 0; itr < mNumNeeds; itr++)
- {
- if (mNeeds[itr].flags & kISpNeedFlag_Utility) continue; // we don't autoconfig to utility needs
-
- if (used[itr] && (mNeeds[itr].flags & kISpNeedFlag_NoMultiConfig)) { continue; }
-
- // pov hat need
- if ((mNeeds[itr].theKind == kISpElementKind_DPad) &&
- ((mNeeds[itr].theLabel == kISpElementLabel_Pad_POV) ||
- (mNeeds[itr].theLabel == kISpElementLabel_Pad_POV_Horiz)))
- {
- WARNING(mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex, "Sidewinder:Movement already assigned!");
-
- mDialogItemToNeedMapping[kDialogItem_StickUp] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = itr;
-
- used[itr] = true;
-
- break;
- }
- }
-
- // third pass axis needs
- for(itr = 0; itr < mNumNeeds; itr++)
- {
- if (mNeeds[itr].flags & kISpNeedFlag_Utility) continue; // we don't autoconfig to utility needs
-
- if (used[itr] && (mNeeds[itr].flags & kISpNeedFlag_NoMultiConfig)) { continue; }
-
- if (mNeeds[itr].theKind != kISpElementKind_Axis) { continue; }
-
- switch(mNeeds[itr].theLabel)
- {
- case kISpElementLabel_Axis_XAxis:
- case kISpElementLabel_Axis_Roll:
- if ((mDialogItemToNeedMapping[kDialogItem_StickLeft] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickRight] == kUnsetIndex))
- {
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickRight] = itr;
-
- used[itr] = true;
- }
- break;
- case kISpElementLabel_Axis_YAxis:
- case kISpElementLabel_Axis_Pitch:
- if ((mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_StickDown] == kUnsetIndex))
- {
- mDialogItemToNeedMapping[kDialogItem_StickUp] = itr;
- mDialogItemToNeedMapping[kDialogItem_StickDown] = itr;
-
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Axis_Rudder:
- case kISpElementLabel_Axis_Yaw:
- if ((mDialogItemToNeedMapping[kDialogItem_RudderLeft] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_RudderRight] == kUnsetIndex))
- {
- mDialogItemToNeedMapping[kDialogItem_RudderLeft] = itr;
- mDialogItemToNeedMapping[kDialogItem_RudderRight] = itr;
-
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Axis_Throttle:
- if ((mDialogItemToNeedMapping[kDialogItem_ThrottleLower] == kUnsetIndex) &&
- (mDialogItemToNeedMapping[kDialogItem_ThrottleHigher] == kUnsetIndex))
- {
- mDialogItemToNeedMapping[kDialogItem_ThrottleLower] = itr;
- mDialogItemToNeedMapping[kDialogItem_ThrottleHigher] = itr;
-
- used[itr] = true;
- }
- break;
-
- }
- }
-
- // fourth and final pass button mNeeds
- for(itr = 0; itr < mNumNeeds; itr++)
- {
- if (mNeeds[itr].flags & kISpNeedFlag_Utility) continue; // we don't autoconfig to utility needs
-
- if (used[itr] && (mNeeds[itr].flags & kISpNeedFlag_NoMultiConfig)) { continue; }
-
- if (mNeeds[itr].theKind != kISpElementKind_Button) { continue; }
-
- switch(mNeeds[itr].theLabel)
- {
- // don't autoconfigure this need
- case kISpElementLabel_Btn_PauseResume:
- break;
-
- case kISpElementLabel_Btn_SlideLeft:
- case kISpElementLabel_Btn_TurnLeft:
- if (mDialogItemToNeedMapping[kDialogItem_StickLeft] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_StickLeft] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_SlideRight:
- case kISpElementLabel_Btn_TurnRight:
- if (mDialogItemToNeedMapping[kDialogItem_StickRight] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_StickRight] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_MoveForward:
- if (mDialogItemToNeedMapping[kDialogItem_StickUp] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_StickUp] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_MoveBackward:
- if (mDialogItemToNeedMapping[kDialogItem_StickDown] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_StickDown] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_LookLeft:
- if (mDialogItemToNeedMapping[kDialogItem_DPadLeft] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_DPadLeft] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_LookRight:
- if (mDialogItemToNeedMapping[kDialogItem_DPadRight] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_DPadRight] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_LookUp:
- if (mDialogItemToNeedMapping[kDialogItem_DPadUp] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_DPadUp] = itr;
- used[itr] = true;
- }
- break;
-
- case kISpElementLabel_Btn_LookDown:
- if (mDialogItemToNeedMapping[kDialogItem_DPadDown] == kUnsetIndex)
- {
- mDialogItemToNeedMapping[kDialogItem_DPadDown] = itr;
- used[itr] = true;
- }
- break;
-
- default:
- // don't configure axis or delta versions of buttons that did not have direction set
- // they probably don't make sense for autoconfiguring
- if ((mNeeds[itr].flags & kISpNeedFlag_Button_AlreadyDelta) ||
- (mNeeds[itr].flags & kISpNeedFlag_Button_AlreadyAxis) )
- break;
-
- // normal button
- if (buttonCount < kNumSidewinderButtons)
- {
- mDialogItemToNeedMapping[kDialogItem_Trigger + buttonCount] = itr;
- buttonCount++;
-
- used[itr] = true;
- }
- break;
- }
- }
-
- // set the low level stuff here
- SetVirtualElements();
- }
-
- OSStatus SidewinderPro::Stop(void)
- {
- // need to mark mVirtualElementValid as false first
- mVirtualElementsValid = false;
-
- if (mReferences) DisposePtr((Ptr) mReferences);
- mReferences = nil;
-
- if (mNeeds) DisposePtr((Ptr) mNeeds);
- mNeeds = nil;
-
- return noErr;
- }
-
- OSStatus SidewinderPro::GetSize(Point &minimum, Point &best)
- {
- best.h = minimum.h = 400;
- best.v = minimum.v = 310;
-
- return noErr;
- }
-
- OSStatus SidewinderPro::HandleEvent(EventRecord &theEvent, Boolean &handled)
- {
- theEvent;
-
- handled = false;
-
- UpdateAllButtons();
-
- return noErr;
- }
-
- OSStatus SidewinderPro::Show(DialogPtr theDialog, short dialogItemNumber, Rect &r)
- {
- OSStatus err;
-
- mRect = r;
-
- mDialog = theDialog;
- mBaseDITLCount = CountDITL(theDialog);
-
- // open the resource file and error check
- mResRef = FSpOpenResFile(&mFileSpec, fsRdPerm);
- err = ::ResError();
- WARNING(err == noErr, "SidewinderPro::Show could not FSpOpenResFile on the Sidewinder ResFile");
- if (err != noErr) { return err; }
-
- // get our DITL and error check
- Handle ditl = Get1Resource('DITL', kDITLID_Config);
- err = ::ResError();
- WARNING(err == noErr, "SidewinderPro::Show could not Get1Resource on the Sidewinder DITL");
- if (err != noErr) { CloseResFile(mResRef); return err; }
-
- // append our DITL
- AppendDITL(theDialog, ditl, -dialogItemNumber);
- WARNING(CountDITL(mDialog) > mBaseDITLCount, "SidewinderPro::Show AppendDITL did not increase DITL count");
-
- // free our DITL
- ReleaseResource(ditl);
-
- // setup the checkboxes
- SetDialogControl(kDialogItem_Checkbox_Reverse_StickVertical, mReverseStickVertical);
- SetDialogControl(kDialogItem_Checkbox_Reverse_HatVertical, mReverseHatVertical);
- SetDialogControl(kDialogItem_Checkbox_Reverse_Rudder, mReverseRudder);
- SetDialogControl(kDialogItem_Checkbox_Reverse_Throttle, mReverseThrottle);
-
- mVisable = true;
-
- // clear out ui indiciators
- for (UInt32 index = 0; index < kDialogItem_NumPopups; index++)
- mPopupPressed[index] = false;
- UpdateAllButtons ();
-
- return noErr;
- }
-
- OSStatus SidewinderPro::Hide(void)
- {
- // restore to original count of items
- ShortenDITL(mDialog, CountDITL(mDialog) - mBaseDITLCount);
- WARNING(CountDITL(mDialog) == mBaseDITLCount, "SidewinderPro::Hide Failed to restore the DITL count");
-
- // mark that we are no longer visable
- mVisable = false;
-
- // clear our mDialog ptr
- mDialog = nil;
-
- // close our res file and assert check
- CloseResFile(mResRef);
- RES_WARNING("SidewinderPro::Hide CloseResFile choked");
-
- return noErr;
- }
-
- OSStatus SidewinderPro::BeginConfiguration(UInt32 count, ISpNeed needs[])
- {
- count;
- needs;
-
- WARNING(mVirtualElementsValid, "BeginConfiguration was called but the virtual elements were not valid");
-
- return noErr;
- }
-
- OSStatus SidewinderPro::EndConfiguration(Boolean accept)
- {
- accept;
-
- WARNING(mVirtualElementsValid, "EndConfiguration was called but the virtual elements were not valid");
-
- SetVirtualElements();
-
- return noErr;
- }
-
- OSStatus SidewinderPro::SetActive(Boolean active)
- {
- if (mActive == active) return noErr;
-
- mActive = active;
-
- // we're responsible for pushing any values which are non-default
- if (mActive) PushAllNonDefaultValues();
-
- return noErr;
- }
-
- /* =============================================================================
- * PushAllNonDefaultValues (private)
- *
- * This is done when activating, as part of our duties as the driver.
- *
- * A driver is responsible for pushing all non-default values when it is
- * activated.
- *
- * the default values for buttons, dpads, deltas and asymmetric axis is zero
- * the default value for symmetric axis is kISpAxisMiddle
- *
- * ========================================================================== */
- OSStatus SidewinderPro::PushAllNonDefaultValues(void)
- {
- AbsoluteTime time = ISpUptime();
-
- // the elements have been reset across suspend, so we need to push anything
- // that is non-default
- SidewinderStateStruct resetState;
- resetState.xAxis = kISpAxisMiddle;
- resetState.yAxis = kISpAxisMiddle;
- resetState.throttle = kISpAxisMinimum;
- resetState.rudder = kISpAxisMiddle;
- resetState.hat = kISpPadIdle;
-
- for (UInt32 itr = 0; itr < kNumSidewinderButtons; itr++)
- { resetState.buttons[itr] = kISpButtonUp; }
-
- // push the low level stuff thats different
-
- if (mOldState.xAxis != resetState.xAxis)
- ISpElement_PushSimpleData(mXAxis, mOldState.xAxis, &time);
- if (mOldState.yAxis != resetState.yAxis)
- ISpElement_PushSimpleData(mYAxis, mOldState.yAxis, &time);
- if (mOldState.throttle != resetState.throttle)
- ISpElement_PushSimpleData(mThrottle, mOldState.throttle, &time);
- if (mOldState.rudder != resetState.rudder)
- ISpElement_PushSimpleData(mRudder, mOldState.rudder, &time);
- if (mOldState.hat != resetState.hat)
- ISpElement_PushSimpleData(mHat, mOldState.hat, &time);
-
- // it's better to assume a button was released while we were deactive
- // than to assume that is it still down. Since we have not been getting
- // called to update changes while we were deactivated, we have to
- // assume one or the other
- {
- for (UInt32 itr = 0; itr < kNumSidewinderButtons; itr++)
- mOldState.buttons[itr] = resetState.buttons[itr];
- }
-
- // if high level is inited, push 'new' values to virtual elements also
- if (mVirtualElementsValid)
- {
- // set mOldHLData to reset state
- StateToHighLevelData (resetState, mOldHLData);
- SetAsFields(mOldHLData);
-
- // set new state to the old low level state
- HighLevelData newHLData;
- StateToHighLevelData (mOldState, newHLData);
- SetAsFields(newHLData);
-
- // push the 'new' values
- PushDataToVirtuals(newHLData);
- }
-
- return noErr;
- }
-
- OSStatus SidewinderPro::GetIcon(short &iconSuiteResourceId)
- {
- iconSuiteResourceId = 128;
-
- return 0;
- }
-
-
- void SidewinderPro::DoReverse(short dialog_item, Boolean &the_boolean)
- {
- the_boolean = !the_boolean;
- SetDialogControl(dialog_item, the_boolean);
- mDirty = true;
- }
-
-
- OSStatus SidewinderPro::DialogItemHit(short itemHit)
- {
- short relHit = itemHit - mBaseDITLCount;
-
- switch (relHit)
- {
- case kDialogItem_Checkbox_Reverse_StickVertical: DoReverse(relHit, mReverseStickVertical); break;
- case kDialogItem_Checkbox_Reverse_HatVertical: DoReverse(relHit, mReverseHatVertical); break;
- case kDialogItem_Checkbox_Reverse_Rudder: DoReverse(relHit, mReverseRudder); break;
- case kDialogItem_Checkbox_Reverse_Throttle: DoReverse(relHit, mReverseThrottle); break;
- }
-
- return noErr;
- }
-
-
- OSStatus SidewinderPro::GetState(UInt32 buflen, void *buffer, UInt32 &length)
- {
- WARNING(mVirtualElementsValid, "SidewinderPro: GetState was called but the virtual elemtns were not valid");
- WARNING((buflen == 0) || (buffer != nil), "SidewinderPro: GetState buffer == nil");
-
- MicrosoftSetVersion1 *set_vers1_ptr = (MicrosoftSetVersion1 *) buffer;
- length = sizeof(MicrosoftSetVersion1);
-
- if (length > buflen) { return noErr; } // required length > space in the buffer, return
-
- UInt32 itr;
- set_vers1_ptr->version = kSetVersion1;
-
- for(itr = 1; itr <= kDialogItem_NumPopups; itr++)
- {
- set_vers1_ptr->mapping[itr - 1] = mDialogItemToNeedMapping[itr]; // set is zero based array
- }
-
- set_vers1_ptr->flags = 0;
-
- if (mReverseStickVertical) { set_vers1_ptr->flags |= kSetReverseStickVertical; }
- if (mReverseHatVertical) { set_vers1_ptr->flags |= kSetReverseHatVertical; }
- if (mReverseRudder) { set_vers1_ptr->flags |= kSetReverseRudder; }
- if (mReverseThrottle) { set_vers1_ptr->flags |= kSetReverseThrottle; }
-
- return noErr;
- }
-
- OSStatus SidewinderPro::SetState(UInt32 length, void *buffer)
- {
- WARNING(mVirtualElementsValid, "SetState was called but the virtual elements were not valid");
- WARNING((length == 0) || (buffer != nil), "SidewinderPro: SetState buffer == nil");
- WARNING((length > 4), "SidewinderPro: SetState length < 4");
-
- UInt32 itr;
-
- // min size check
- if (length < 4) { return -1;}
-
- UInt32 version = * ((UInt32 *) buffer);
-
- switch(version)
- {
- case kSetVersion1:
- if (length == sizeof(MicrosoftSetVersion1))
- {
- MicrosoftSetVersion1 *set_vers1_ptr = (MicrosoftSetVersion1 *) buffer;
-
- for(itr = 1; itr <= kDialogItem_NumPopups; itr++)
- {
- mDialogItemToNeedMapping[itr] = set_vers1_ptr->mapping[itr - 1]; // set is zero based array
- }
-
- mReverseStickVertical = (set_vers1_ptr->flags & kSetReverseStickVertical) > 0;
- mReverseHatVertical = (set_vers1_ptr->flags & kSetReverseHatVertical) > 0;
- mReverseRudder = (set_vers1_ptr->flags & kSetReverseRudder) > 0;
- mReverseThrottle = (set_vers1_ptr->flags & kSetReverseThrottle) > 0;
- }
- break;
- }
-
- SetVirtualElements();
-
- if (mVisable)
- {
- Draw ();
-
- SetDialogControl(kDialogItem_Checkbox_Reverse_StickVertical, mReverseStickVertical);
- SetDialogControl(kDialogItem_Checkbox_Reverse_HatVertical, mReverseHatVertical);
- SetDialogControl(kDialogItem_Checkbox_Reverse_Rudder, mReverseRudder);
- SetDialogControl(kDialogItem_Checkbox_Reverse_Throttle, mReverseThrottle);
- }
-
- mDirty = false;
-
- return noErr;
- }
-
- OSStatus SidewinderPro::Tickle(void)
- {
- return noErr;
- }
-
- void SidewinderPro::SetAsFields(HighLevelData ¤t)
- {
- AxisToButtons(current.xAxis, current.xAxis_as_buttons);
- AxisToButtons(current.yAxis, current.yAxis_as_buttons);
- AxisToButtons(current.throttle, current.throttle_as_buttons);
- AxisToButtons(current.rudder, current.rudder_as_buttons);
-
- DPadToButtonsAndAxis(current.hat, current.hat_as_buttons, current.hat_as_axis);
- }
-
- void SidewinderPro::PushDataToVirtuals(HighLevelData ¤t)
- {
- WARNING(mVirtualElementsValid, "PushDataToVirtuals mVirtualElementsValid was false");
-
- OSStatus err;
- AbsoluteTime time = ISpUptime();
-
- // x and y axis
- if (((current.xAxis != mOldHLData.xAxis) || (current.yAxis != mOldHLData.yAxis)) && (mVirtuals.stickMovement || mVirtuals.stickDPad))
- {
- ISpMovementData moveData;
-
- moveData.xAxis = current.xAxis;
- moveData.yAxis = current.yAxis;
-
- moveData.direction = AxisToDPad(moveData.xAxis, moveData.yAxis);
-
- if (mVirtuals.stickMovement != nil)
- {
- err = ISpElement_PushComplexData(mVirtuals.stickMovement, sizeof (moveData), &moveData, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if (mVirtuals.stickDPad != nil)
- {
- err = ISpElement_PushSimpleData(mVirtuals.stickDPad, moveData.direction, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
- }
-
- // *************** X AXIS ***************
- if ((current.xAxis != mOldHLData.xAxis) && (mVirtuals.xAxis != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.xAxis, current.xAxis, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.xAxis_as_buttons[0] != mOldHLData.xAxis_as_buttons[0]) && (mVirtuals.xAxis_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.xAxis_as_buttons[0], current.xAxis_as_buttons[0], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.xAxis_as_buttons[1] != mOldHLData.xAxis_as_buttons[1]) && (mVirtuals.xAxis_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.xAxis_as_buttons[1], current.xAxis_as_buttons[1], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- // *************** Y AXIS ***************
- if ((current.yAxis != mOldHLData.yAxis) && (mVirtuals.yAxis != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.yAxis, current.yAxis, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.yAxis_as_buttons[0] != mOldHLData.yAxis_as_buttons[0]) && (mVirtuals.yAxis_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.yAxis_as_buttons[0], current.yAxis_as_buttons[0], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.yAxis_as_buttons[1] != mOldHLData.yAxis_as_buttons[1]) && (mVirtuals.yAxis_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.yAxis_as_buttons[1], current.yAxis_as_buttons[1], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- // *************** THROTTLE ***************
- if ((current.throttle != mOldHLData.throttle) && (mVirtuals.throttle != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.throttle, current.throttle, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.throttle_as_buttons[0] != mOldHLData.throttle_as_buttons[0]) && (mVirtuals.throttle_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.throttle_as_buttons[0], current.throttle_as_buttons[0], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.throttle_as_buttons[1] != mOldHLData.throttle_as_buttons[1]) && (mVirtuals.throttle_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.throttle_as_buttons[1], current.throttle_as_buttons[1], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- // *************** RUDDER ***************
- if ((current.rudder != mOldHLData.rudder) && (mVirtuals.rudder != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.rudder, current.rudder, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.rudder_as_buttons[0] != mOldHLData.rudder_as_buttons[0]) && (mVirtuals.rudder_as_buttons[0] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.rudder_as_buttons[0], current.rudder_as_buttons[0], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- if ((current.rudder_as_buttons[1] != mOldHLData.rudder_as_buttons[1]) && (mVirtuals.rudder_as_buttons[1] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.rudder_as_buttons[1], current.rudder_as_buttons[1], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- // *************** DPAD ***************
- if ((current.hat != mOldHLData.hat) && (mVirtuals.hat != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.hat, current.hat, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
-
- UInt32 hat_button_itr;
- for(hat_button_itr = 0; hat_button_itr < 4; hat_button_itr++)
- {
- ISpElementReference this_hat_button_element = mVirtuals.hat_as_buttons[hat_button_itr];
- UInt32 cur_hat_button_data = current.hat_as_buttons[hat_button_itr];
- UInt32 old_hat_button_data = mOldHLData.hat_as_buttons[hat_button_itr];
-
- if ((cur_hat_button_data != old_hat_button_data) && (this_hat_button_element != nil))
- {
- err = ISpElement_PushSimpleData(this_hat_button_element, cur_hat_button_data, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
- }
-
- Boolean axisDataChanged = false;
-
- UInt32 hat_axis_itr;
- for(hat_axis_itr = 0; hat_axis_itr < 2; hat_axis_itr++)
- {
- ISpElementReference this_hat_axis_element = mVirtuals.hat_as_axis[hat_axis_itr];
- UInt32 cur_hat_axis_data = current.hat_as_axis[hat_axis_itr];
- UInt32 old_hat_axis_data = mOldHLData.hat_as_axis[hat_axis_itr];
-
- if (cur_hat_axis_data != old_hat_axis_data)
- {
- axisDataChanged = true;
-
- if (this_hat_axis_element != nil)
- {
- err = ISpElement_PushSimpleData(this_hat_axis_element, cur_hat_axis_data, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
- }
- }
-
- if (axisDataChanged && mVirtuals.hat_as_movement)
- {
- ISpMovementData moveData;
-
- moveData.xAxis = current.hat_as_axis[0];
- moveData.yAxis = current.hat_as_axis[1];
-
- moveData.direction = current.hat;
-
- if (mVirtuals.hat_as_movement != nil)
- {
- err = ISpElement_PushComplexData(mVirtuals.hat_as_movement, sizeof (moveData), &moveData, &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
- }
-
- // *************** BUTTONS ***************
- UInt32 button_itr;
- for(button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- {
- if ((current.buttons[button_itr] != mOldHLData.buttons[button_itr]) && (mVirtuals.buttons[button_itr] != nil))
- {
- err = ISpElement_PushSimpleData(mVirtuals.buttons[button_itr], current.buttons[button_itr], &time);
- WARNING(err == noErr, "SidewinderPro::PushDataToVirtuals ISpElement_PushSimpleData failed");
- }
- }
- }
-
- OSStatus SidewinderPro::InterruptTickle(void)
- {
- return noErr;
- }
-
- OSStatus SidewinderPro::Draw(void)
- {
- Str255 titleStr;
- Rect titleRect;
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_Stick);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_Stick, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_POVHat);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_POVHat, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_Throttle);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_Throttle, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_Rudder);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_Rudder, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_StickButtons);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_StickButtons, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- GetIndString (titleStr, kStrList_Main, kStrList_Main_BaseButtons);
- DialogItem_GetRect(mDialog, mBaseDITLCount + kDialogItem_GroupBox_BaseButtons, &titleRect);
- GScGroupBox_SecondaryNamed_Draw(&titleRect, titleStr, kGSActive);
-
- for(UInt32 itr = kDialogItem_FirstPopup; itr <= kDialogItem_NumPopups; itr++)
- { PlotPopupIcon(itr + mBaseDITLCount, ttNone); }
-
- return noErr;
- }
-
- OSStatus SidewinderPro::Click(const EventRecord &event)
- {
- // Find the point in local coords
- Point where;
- where = event.where;
- GlobalToLocal(&where);
-
- UInt32 itr;
-
- for(itr = kDialogItem_FirstPopup; itr <= kDialogItem_NumPopups; itr++)
- {
- short itemNo = itr + mBaseDITLCount;
- UInt32 oldNeed = mDialogItemToNeedMapping[itr];
- UInt32 newNeed;
-
- switch (itr)
- {
- case kDialogItem_StickUp:
- case kDialogItem_StickDown:
- HandleStickClick (where, itemNo, kDialogItem_StickUp, kDialogItem_StickDown,
- kDialogItem_StickLeft, kDialogItem_StickRight, oldNeed, newNeed);
- break;
-
- case kDialogItem_StickLeft:
- case kDialogItem_StickRight:
- HandleStickClick (where, itemNo, kDialogItem_StickUp, kDialogItem_StickDown,
- kDialogItem_StickLeft, kDialogItem_StickRight, oldNeed, newNeed);
- break;
-
- case kDialogItem_ThrottleLower:
- case kDialogItem_ThrottleHigher:
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_Throttle, kDialogItem_ThrottleLower, kDialogItem_ThrottleHigher, oldNeed, newNeed);
- break;
-
- case kDialogItem_RudderLeft:
- case kDialogItem_RudderRight:
- HandleAxisClick (where, itemNo, kISpElementLabel_Axis_Rudder, kDialogItem_RudderLeft, kDialogItem_RudderRight, oldNeed, newNeed);
- break;
-
- case kDialogItem_Trigger:
- HandleButtonClick (where, itemNo, kISpElementLabel_Btn_Fire, oldNeed, newNeed);
- break;
-
-
- case kDialogItem_TopButton:
- case kDialogItem_StickHighButton:
- case kDialogItem_StickLowButton:
- case kDialogItem_BaseFarLeft:
- case kDialogItem_BaseFarRight:
- case kDialogItem_BaseNearLeft:
- case kDialogItem_BaseNearRight:
- HandleButtonClick (where, itemNo, kISpElementLabel_None, oldNeed, newNeed);
- break;
-
- case kDialogItem_DPadUp:
- case kDialogItem_DPadLeft:
- case kDialogItem_DPadDown:
- case kDialogItem_DPadRight:
- HandleDPadClick (where, itemNo,
- kDialogItem_DPadUp, kDialogItem_DPadDown,
- kDialogItem_DPadLeft, kDialogItem_DPadRight, oldNeed, newNeed);
- break;
-
- default:
- break;
- }
- }
-
- return noErr;
- }
-
-
- OSStatus SidewinderPro::ADBReInit(Boolean inPostProcess)
- {
- UInt32 itr;
-
- switch(inPostProcess)
- {
- case false:
- // remember if we must patch
- mMustRestorePatch = mPatched;
-
- // if required unpatch
- if (mPatched) { Unpatch(); }
-
- // clear our adb address
- mADBAddress = 16;
-
- // zero the device table
- for(itr = 0; itr < 16; itr++) { gSidewinders[itr] = nil; }
-
- // make us an orphan
- mOrphan = true;
- break;
-
- case true:
- UInt32 deviceTableIndex;
- for (deviceTableIndex = CountADBs(); deviceTableIndex > 0; deviceTableIndex--)
- {
- ADBDataBlock adbDataBlock; // data block for the device refered to by device_table_index
- ADBAddress adbAddress; // adb address for the device refered to by device_table_index
- Boolean isSideWinder;
-
- // is this device table index a sidewinder ?
- isSideWinder = IsSideWinder(deviceTableIndex);
-
- // not a sidewinder, skip it
- if (!isSideWinder) { continue; }
-
- // get this adb address
- adbAddress = GetIndADB(&adbDataBlock, deviceTableIndex);
-
- // this sidewinder is in use already
- if (gSidewinders[adbAddress] != nil) { continue; }
-
- // this is a sidewinder pro and an empty slot
- // take it and break out (one slot per customer)
- mADBAddress = adbAddress;
- gSidewinders[adbAddress] = this;
- mOrphan = false;
- break;
- }
-
- if (mOrphan)
- {
- for(itr = 0; itr < 16; itr++)
- {
- // this sidewinder is in use already
- if (gSidewinders[itr] != nil) { continue; }
-
- // this is an empty slot
- // take it and break out (one slot per customer)
- mADBAddress = 16; // invalid
- gSidewinders[itr] = this;
- mOrphan = true;
- break;
- }
- }
-
- if (mMustRestorePatch) { Patch(); }
-
- break;
- }
-
- return noErr;
- }
-
- /*
- *
- * SetVirtualElements
- *
- * This function takes the virtual index stuff and sets our virtual elements;
- *
- */
-
- void SidewinderPro::SetVirtualElements(void)
- {
- WARNING(mNeeds != nil, "SidewinderPro::SetVirtualElements but mNeeds was nil");
- WARNING(mReferences != nil, "SidewinderPro::SetVirtualElements but mReferences was nil");
- WARNING(mDialogItemToNeedMapping != nil, "SidewinderPro::SetVirtualElements but mDialogItemToNeedMapping was nil");
-
- #if DEBUG
- {
- UInt32 debug_mapping_itr;
-
- for(debug_mapping_itr = 0; debug_mapping_itr < kDialogItem_NumPopups+1; debug_mapping_itr++)
- {
- UInt32 debug_mapping = mDialogItemToNeedMapping[debug_mapping_itr];
- WARNING(((debug_mapping == kUnsetIndex) || (debug_mapping < mNumNeeds)), "SidewinderPro::SetVirtualElements out of range");
- }
- }
- #endif
-
- ClearVirtuals();
-
- UInt32 need;
-
- // stick up: up button, y axis and movement
- need = mDialogItemToNeedMapping[kDialogItem_StickUp];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Movement: mVirtuals.stickMovement = mReferences[need]; break;
- case kISpElementKind_DPad: mVirtuals.stickDPad = mReferences[need]; break;
- case kISpElementKind_Axis: mVirtuals.yAxis = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.yAxis_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // stick down: down button
- need = mDialogItemToNeedMapping[kDialogItem_StickDown];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.yAxis_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // stick left: left button and x axis
- need = mDialogItemToNeedMapping[kDialogItem_StickLeft];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: mVirtuals.xAxis = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.xAxis_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // stick right: right button
- need = mDialogItemToNeedMapping[kDialogItem_StickRight];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.xAxis_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // throttle lower: min button and throttle axis
- need = mDialogItemToNeedMapping[kDialogItem_ThrottleLower];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: mVirtuals.throttle = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.throttle_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // throttle higher: max button
- need = mDialogItemToNeedMapping[kDialogItem_ThrottleHigher];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.throttle_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // rudder lower: min button and rudder axis
- need = mDialogItemToNeedMapping[kDialogItem_RudderLeft];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: mVirtuals.rudder = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.rudder_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // rudder higher: max button
- need = mDialogItemToNeedMapping[kDialogItem_RudderRight];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.rudder_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // hat up: up button, y axis, movement, hat
- need = mDialogItemToNeedMapping[kDialogItem_DPadUp];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_DPad: mVirtuals.hat = mReferences[need]; break;
- case kISpElementKind_Movement: mVirtuals.hat_as_movement = mReferences[need]; break;
- case kISpElementKind_Axis: mVirtuals.hat_as_axis[1] = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.hat_as_buttons[0] = mReferences[need]; break;
- }
- }
-
- // hat down: down button
- need = mDialogItemToNeedMapping[kDialogItem_DPadDown];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.hat_as_buttons[2] = mReferences[need]; break;
- }
- }
-
- // hat left: left button and x axis
- need = mDialogItemToNeedMapping[kDialogItem_DPadLeft];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Axis: mVirtuals.hat_as_axis[0] = mReferences[need]; break;
- case kISpElementKind_Button: mVirtuals.hat_as_buttons[1] = mReferences[need]; break;
- }
- }
-
- // hat right: right button
- need = mDialogItemToNeedMapping[kDialogItem_DPadRight];
- if (need != kUnsetIndex)
- {
- switch (mNeeds[need].theKind)
- {
- case kISpElementKind_Button: mVirtuals.hat_as_buttons[3] = mReferences[need]; break;
- }
- }
-
- // buttons
- for (UInt32 button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- {
- need = mDialogItemToNeedMapping[kDialogItem_Trigger + button_itr];
-
- if (need != kUnsetIndex)
- { mVirtuals.buttons[button_itr] = mReferences[need]; }
- }
- }
-
- void SidewinderPro::ClearVirtuals (void)
- {
- mVirtuals.xAxis = nil;
- mVirtuals.yAxis = nil;
- mVirtuals.throttle = nil;
- mVirtuals.rudder = nil;
-
- mVirtuals.stickMovement = nil;
- mVirtuals.stickDPad = nil;
-
- mVirtuals.xAxis_as_buttons[0] = nil;
- mVirtuals.yAxis_as_buttons[0] = nil;
- mVirtuals.throttle_as_buttons[0] = nil;
- mVirtuals.rudder_as_buttons[0] = nil;
-
- mVirtuals.xAxis_as_buttons[1] = nil;
- mVirtuals.yAxis_as_buttons[1] = nil;
- mVirtuals.throttle_as_buttons[1] = nil;
- mVirtuals.rudder_as_buttons[1] = nil;
-
- mVirtuals.hat = nil;
- mVirtuals.hat_as_movement = nil;
- mVirtuals.hat_as_buttons[0] = nil;
- mVirtuals.hat_as_buttons[1] = nil;
- mVirtuals.hat_as_buttons[2] = nil;
- mVirtuals.hat_as_buttons[3] = nil;
- mVirtuals.hat_as_axis[0] = nil;
- mVirtuals.hat_as_axis[1] = nil;
-
- // buttons
- UInt32 button_itr;
- for(button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- {
- mVirtuals.buttons[button_itr] = nil;
- }
- }
-
-
- OSStatus SidewinderPro::Initialize(FSSpec fileSpec)
- {
- OSStatus err;
- UInt32 count = 0; // number of sidewinders
- short resource_ref = -1; // ref to our resource file
- Boolean resource_file_open = false; // true if our resource file is open, (we open if we find a device)
-
- UInt32 device_table_index; // used w/ CountADBs and GetIndADB starts at the top counts down
-
- for (device_table_index = CountADBs(); device_table_index > 0; device_table_index--)
- {
- ADBDataBlock adbDataBlock; // data block for the device refered to by device_table_index
- ADBAddress adbAddress; // adb address for the device refered to by device_table_index
- Boolean isSideWinder;
-
- isSideWinder = IsSideWinder(device_table_index);
- if (!isSideWinder) { continue; }
-
- // get information for this adb address
- adbAddress = GetIndADB(&adbDataBlock, device_table_index);
-
- // open the resource file and check for errors
- if (!resource_file_open)
- {
- resource_ref = FSpOpenResFile(&fileSpec, fsRdPerm);
- err = ResError();
-
- // assert and error check
- WARNING(err == noErr, "SidewinderPro::Initialize failed to open res file");
- if (err != noErr) { return err; }
-
- resource_file_open = true; // used to know to close res file
- }
-
- // this is a sidewinder pro, create the device
- gSidewinders[adbAddress] = new SidewinderPro(adbAddress, fileSpec);
-
- // assert and error check
- WARNING(gSidewinders[adbAddress] != nil, "SidewinderPro failed to allocate");
-
-
- // increment our count
- count++;
- }
-
- // if needed close the resource file
- if (resource_file_open) { CloseResFile(resource_ref); }
-
- return noErr;
- }
-
- Boolean SidewinderPro::IsSideWinder(short inDeviceTableIndex)
- {
- const char kSidewinderProOrigAddress = 4; // original address
- ADBDataBlock adbDataBlock; // data block for the device refered to by device_table_index
- ADBAddress adbAddress; // adb address for the device refered to by device_table_index
-
- // get information for this adb address
- adbAddress = GetIndADB(&adbDataBlock, inDeviceTableIndex);
-
- // correct original address ?
- if (adbDataBlock.origADBAddr != kSidewinderProOrigAddress)
- { return false; }
-
- // read reg 3 to determine handler id
- UInt8 register_three[9];
- ADBOp_TalkSync(adbAddress, 3, register_three);
-
- // does register 3 have a valid length ?
- if (register_three[0] != 2)
- { return false; }
-
- // is handler id correct ?
- if (register_three[2] != kHandlerID_Addr4_Sidewinder3DPro)
- { return false; }
-
- // passed all the checks must be a sidewinder
- return true;
- }
-
- /* =============================================================================
- * Terminate (public, static)
- *
- * Gets rid of all our devices.
- * ========================================================================== */
- void SidewinderPro::Terminate(
- void)
- {
- ADBAddress itr;
-
- // get rid of all the SidewinderPro devices
- for(itr = 0; itr < 15; itr++)
- {
- if (gSidewinders[itr] != nil) { delete gSidewinders[itr]; }
- }
- }
-
-
- void SidewinderPro::ParseData(
- void *inBuffer,
- UInt32 inCommand)
- {
- OSStatus err;
- const UInt8 kHiNibble = 0x10 | 0x20 | 0x40 | 0x80;
- const UInt8 kLoNibble = 0x01 | 0x02 | 0x04 | 0x08;
-
- if (mActive && (inCommand & 0x0F) == 0x0C)
- {
- AbsoluteTime time = ISpUptime();
-
- // Parse the data from "Talk R0" -- xy deltas and buttons
- UInt8* buffer = (UInt8*) inBuffer;
- SidewinderStateStruct state;
-
- if (buffer[0] != 7) { return; }
-
- // parse the raw axis packets
- state.xAxis = ((buffer[1] & kLoNibble) << 6) | (buffer[2] >> 2); // 4 + 6 = 10 bits of x
- state.yAxis = ((buffer[2] & 0x03) << 8) | buffer[3]; // 2 + 8 = 10 bits of y
- state.throttle = ((buffer[6] & 0x03) << 8) | buffer[7]; // 2 + 8 = 10 bits of throttle
- state.rudder = ((buffer[4] & 0x01) << 8) | buffer[5]; // 1 + 8 = 9 bits of rudder
-
- WARNING(state.xAxis <= 0x3ff, "SidewinderPro::ParseData xAxis has more than 10 bits of data");
- WARNING(state.yAxis <= 0x3ff, "SidewinderPro::ParseData yAxis has more than 10 bits of data");
- WARNING(state.throttle <= 0x3ff, "SidewinderPro::ParseData throttle has more than 10 bits of data");
- WARNING(state.rudder <= 0x1ff, "SidewinderPro::ParseData rudder has more than 9 bits of data");
-
- // reverse axis to transform to ISp coordinate system
- state.yAxis = 0x3ff - state.yAxis;
- state.throttle = 0x3ff - state.throttle;
-
- // read and convert the hat
- state.hat = (buffer[4] & kHiNibble) >> 4; // hat
-
- WARNING(state.hat <= 8, "SidewinderPro::ParseData hat should be 0..8");
- switch(state.hat)
- {
- case 0: state.hat = kISpPadIdle; break;
- case 1: state.hat = kISpPadUp; break;
- case 2: state.hat = kISpPadUpRight; break;
- case 3: state.hat = kISpPadRight; break;
- case 4: state.hat = kISpPadDownRight; break;
- case 5: state.hat = kISpPadDown; break;
- case 6: state.hat = kISpPadDownLeft; break;
- case 7: state.hat = kISpPadLeft; break;
- case 8: state.hat = kISpPadUpLeft; break;
- default: state.hat = kISpPadIdle; break;
- }
-
- // read the buttons
- state.buttons[kTrigger] = !(buffer[6] & 0x10); // trigger
- state.buttons[kTopButton] = !(buffer[6] & 0x20); // thumb
- state.buttons[kStickHighButton] = !(buffer[6] & 0x40); // stick hi
- state.buttons[kStickLowButton] = !(buffer[6] & 0x80); // stick lo
-
- state.buttons[kBaseFarLeft] = !(buffer[1] & 0x10); // top left
- state.buttons[kBaseFarRight] = !(buffer[1] & 0x20); // top right
- state.buttons[kBaseNearLeft] = !(buffer[1] & 0x80); // low left
- state.buttons[kBaseNearRight] = !(buffer[1] & 0x40); // low right
-
- // scale and calibrate
- state.xAxis = state.xAxis << 22;
- state.yAxis = state.yAxis << 22;
- state.throttle = state.throttle << 22;
- state.rudder = state.rudder << 23;
-
- // push the data where it changed
- if (state.xAxis != mOldState.xAxis)
- {
- err = ISpElement_PushSimpleData(mXAxis, state.xAxis, &time);
- WARNING(err == noErr, "push failed in parse");
- }
-
- if (state.yAxis != mOldState.yAxis)
- {
- err = ISpElement_PushSimpleData(mYAxis, state.yAxis, &time);
- WARNING(err == noErr, "push failed in parse");
- }
-
- if (state.throttle != mOldState.throttle)
- {
- err = ISpElement_PushSimpleData(mThrottle, state.throttle, &time);
- WARNING(err == noErr, "push failed in parse");
- }
-
- if (state.rudder != mOldState.rudder)
- {
- err = ISpElement_PushSimpleData(mRudder, state.rudder, &time);
- WARNING(err == noErr, "push failed in parse");
- }
-
- if (state.hat != mOldState.hat)
- {
- err = ISpElement_PushSimpleData(mHat, state.hat, &time);
- WARNING(err == noErr, "push failed in parse");
- }
-
- UInt32 button_itr;
- for(button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- {
- if (state.buttons[button_itr] != mOldState.buttons[button_itr])
- {
- err = ISpElement_PushSimpleData(mButtons[button_itr], state.buttons[button_itr], &time);
- WARNING(err == noErr, "push failed for generic button");
- }
- }
-
- HighLevelData currentHLData;
- StateToHighLevelData (state, currentHLData);
-
- // if we are in high level mode do the high level actions
- if (mVirtualElementsValid)
- {
- SetAsFields(currentHLData);
- PushDataToVirtuals(currentHLData);
- }
-
- mOldState = state;
- mOldHLData = currentHLData;
- }
- }
-
- #if !__MWERKS__
- inline
- #endif
- void SidewinderPro::StateToHighLevelData(const SidewinderStateStruct &inState, HighLevelData& outHLData)
- {
- outHLData.xAxis = inState.xAxis;
- outHLData.yAxis = inState.yAxis;
- outHLData.throttle = inState.throttle;
- outHLData.rudder = inState.rudder;
- outHLData.hat = inState.hat;
-
- for (UInt32 button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- outHLData.buttons[button_itr] = inState.buttons[button_itr];
-
- // axis reversal
- if (mReverseStickVertical)
- outHLData.yAxis = kISpAxisMaximum - outHLData.yAxis;
- if (mReverseThrottle)
- outHLData.throttle = kISpAxisMaximum - outHLData.throttle;
- if (mReverseRudder)
- outHLData.rudder = kISpAxisMaximum - outHLData.rudder;
- if (mReverseHatVertical)
- outHLData.hat = DPadReverseVertical (outHLData.hat);
- }
-
-
- /*
- *
- * IsPressed
- *
- * This function returns true if this dialog item 'pressed' (ie on the device)
- *
- */
-
- Boolean SidewinderPro::IsPressed (short inDialogItem)
- {
- UInt32 array_index = inDialogItem - mBaseDITLCount - kDialogItem_FirstPopup;
-
- WARNING(array_index >= 0, "IsPressed array_index out of range (to small)");
- WARNING(array_index < kDialogItem_NumPopups, "IsPressed array_index out of range (to large)");
-
- return mPopupPressed[array_index];
- }
-
- void SidewinderPro::UpdateAllButtons(void)
- {
- HighLevelData theHLData = mOldHLData;
-
- UpdateSingleButton (theHLData.xAxis_as_buttons[0], kDialogItem_StickLeft);
- UpdateSingleButton (theHLData.xAxis_as_buttons[1], kDialogItem_StickRight);
- UpdateSingleButton (theHLData.yAxis_as_buttons[0], kDialogItem_StickDown);
- UpdateSingleButton (theHLData.yAxis_as_buttons[1], kDialogItem_StickUp);
-
- UpdateSingleButton (theHLData.throttle_as_buttons[0], kDialogItem_ThrottleLower);
- UpdateSingleButton (theHLData.throttle_as_buttons[1], kDialogItem_ThrottleHigher);
-
- UpdateSingleButton (theHLData.rudder_as_buttons[0], kDialogItem_RudderLeft);
- UpdateSingleButton (theHLData.rudder_as_buttons[1], kDialogItem_RudderRight);
-
- for(UInt32 button_itr = 0; button_itr < kNumSidewinderButtons; button_itr++)
- UpdateSingleButton(theHLData.buttons[button_itr], kDialogItem_Trigger + button_itr);
-
- UpdateSingleButton (theHLData.hat_as_buttons[0], kDialogItem_DPadUp);
- UpdateSingleButton (theHLData.hat_as_buttons[2], kDialogItem_DPadDown);
- UpdateSingleButton (theHLData.hat_as_buttons[1], kDialogItem_DPadLeft);
- UpdateSingleButton (theHLData.hat_as_buttons[3], kDialogItem_DPadRight);
- }
-
- void SidewinderPro::UpdateSingleButton(UInt32 curButton, UInt32 index)
- {
- WARNING(mDialog != nil, "SidewinderPro::UpdateSingleButton mDialog was nil");
- WARNING(mVisable, "SidewinderPro::UpdateSingleButton mVisable was false");
-
- WARNING(index > 0, "SidewinderPro::UpdateSingleButton index out of range (to small)");
- WARNING(index <= kDialogItem_NumPopups, "SidewinderPro::UpdateSingleButton index out of range (to large)");
-
- UInt32 array_index = index - kDialogItem_FirstPopup;
- Boolean changed = false;
-
- if ((!mPopupPressed[array_index]) && (curButton))
- {
- mPopupPressed[array_index] = true;
- changed = true;
- }
- else if ((mPopupPressed[array_index]) && (!curButton))
- {
- mPopupPressed[array_index] = false;
- changed = true;
- }
-
- if (changed)
- { PlotPopupIcon(mBaseDITLCount + index, ttNone); }
- }
-
-